
(function(window,document,Laya){
	var __un=Laya.un,__uns=Laya.uns,__static=Laya.static,__class=Laya.class,__getset=Laya.getset,__newvec=Laya.__newvec;

	var BlendMode=laya.webgl.canvas.BlendMode,Event=laya.events.Event,HTMLCanvas=laya.resource.HTMLCanvas;
	var Handler=laya.utils.Handler,IndexBuffer2D=laya.webgl.utils.IndexBuffer2D,Loader=laya.net.Loader,MathUtil=laya.maths.MathUtil;
	var Matrix=laya.maths.Matrix,Render=laya.renders.Render,RenderContext=laya.renders.RenderContext,RenderSprite=laya.renders.RenderSprite;
	var Shader=laya.webgl.shader.Shader,Sprite=laya.display.Sprite,Stage=laya.display.Stage,Stat=laya.utils.Stat;
	var Texture=laya.resource.Texture,Timer=laya.utils.Timer,Utils=laya.utils.Utils,Value2D=laya.webgl.shader.d2.value.Value2D;
	var VertexBuffer2D=laya.webgl.utils.VertexBuffer2D,WebGL=laya.webgl.WebGL,WebGLContext=laya.webgl.WebGLContext;
	/**
	*<code>EmitterBase</code> 类是粒子发射器类
	*/
	//class laya.particle.emitter.EmitterBase
	var EmitterBase=(function(){
		function EmitterBase(){
			this._frameTime=0;
			this._emissionRate=60;
			this._emissionTime=0;
			this.minEmissionTime=1 / 60;
			this._particleTemplate=null;
		}

		__class(EmitterBase,'laya.particle.emitter.EmitterBase');
		var __proto=EmitterBase.prototype;
		/**
		*开始发射粒子
		*@param duration 发射持续的时间
		*/
		__proto.start=function(duration){
			(duration===void 0)&& (duration=1.7976931348623157e+308);
			if (this._emissionRate !=0)
				this._emissionTime=duration;
		}

		/**
		*停止发射粒子
		*@param clearParticles 是否清理当前的粒子
		*/
		__proto.stop=function(){
			this._emissionTime=0;
		}

		/**
		*清理当前的活跃粒子
		*@param clearTexture 是否清理贴图数据,若清除贴图数据将无法再播放
		*/
		__proto.clear=function(){
			this._emissionTime=0;
		}

		/**
		*发射一个粒子
		*
		*/
		__proto.emit=function(){}
		/**
		*时钟前进
		*@param passedTime 前进时间
		*
		*/
		__proto.advanceTime=function(passedTime){
			(passedTime===void 0)&& (passedTime=1);
			this._emissionTime-=passedTime;
			if (this._emissionTime < 0)return;
			this._frameTime+=passedTime;
			if (this._frameTime < this.minEmissionTime)return;
			while (this._frameTime > this.minEmissionTime){
				this._frameTime-=this.minEmissionTime;
				this.emit();
			}
		}

		/**
		*设置粒子粒子模板
		*@param particleTemplate 粒子模板
		*
		*/
		__getset(0,__proto,'particleTemplate',null,function(particleTemplate){
			this._particleTemplate=particleTemplate;
		});

		/**
		*设置粒子发射速率
		*@param emissionRate 粒子发射速率 (个/秒)
		*/
		/**
		*获取粒子发射速率
		*@return 发射速率 粒子发射速率 (个/秒)
		*/
		__getset(0,__proto,'emissionRate',function(){
			return this._emissionRate;
			},function(_emissionRate){
			if (_emissionRate <=0)return;
			this._emissionRate=_emissionRate;
			(_emissionRate > 0)&& (this.minEmissionTime=1 / _emissionRate);
		});

		return EmitterBase;
	})()


	/**
	*@private
	*/
	//class laya.particle.ParticleData
	var ParticleData=(function(){
		function ParticleData(){
			this.position=null;
			this.velocity=null;
			this.startColor=null;
			this.endColor=null;
			this.sizeRotation=null;
			this.radius=null;
			this.radian=null;
			this.durationAddScale=NaN;
			this.time=NaN;
		}

		__class(ParticleData,'laya.particle.ParticleData');
		ParticleData.Create=function(settings,position,velocity,time){
			var particleData=new ParticleData();
			particleData.position=position;
			MathUtil.scaleVector3(velocity,settings.emitterVelocitySensitivity,ParticleData._tempVelocity);
			var horizontalVelocity=MathUtil.lerp(settings.minHorizontalVelocity,settings.maxHorizontalVelocity,Math.random());
			var horizontalAngle=Math.random()*Math.PI *2;
			ParticleData._tempVelocity[0]+=horizontalVelocity *Math.cos(horizontalAngle);
			ParticleData._tempVelocity[2]+=horizontalVelocity *Math.sin(horizontalAngle);
			ParticleData._tempVelocity[1]+=MathUtil.lerp(settings.minVerticalVelocity,settings.maxVerticalVelocity,Math.random());
			particleData.velocity=ParticleData._tempVelocity;
			particleData.startColor=ParticleData._tempStartColor;
			particleData.endColor=ParticleData._tempEndColor;
			var i=0;
			if (settings.disableColor){
				for (i=0;i < 3;i++){
					particleData.startColor[i]=255;
					particleData.endColor[i]=255;
				}
				particleData.startColor[i]=MathUtil.lerp(settings.minStartColor[i],settings.maxStartColor[i],Math.random());
				particleData.endColor[i]=MathUtil.lerp(settings.minEndColor[i],settings.maxEndColor[i],Math.random());
			}
			else{
				if (settings.colorComponentInter){
					for (i=0;i < 4;i++){
						particleData.startColor[i]=MathUtil.lerp(settings.minStartColor[i],settings.maxStartColor[i],Math.random());
						particleData.endColor[i]=MathUtil.lerp(settings.minEndColor[i],settings.maxEndColor[i],Math.random());
					}
					}else {
					MathUtil.lerpVector4(settings.minStartColor,settings.maxStartColor,Math.random(),particleData.startColor);
					MathUtil.lerpVector4(settings.minEndColor,settings.maxEndColor,Math.random(),particleData.endColor);
				}
			}
			particleData.sizeRotation=ParticleData._tempSizeRotation;
			var sizeRandom=Math.random();
			particleData.sizeRotation[0]=MathUtil.lerp(settings.minStartSize,settings.maxStartSize,sizeRandom);
			particleData.sizeRotation[1]=MathUtil.lerp(settings.minEndSize,settings.maxEndSize,sizeRandom);
			particleData.sizeRotation[2]=MathUtil.lerp(settings.minRotateSpeed,settings.maxRotateSpeed,Math.random());
			particleData.radius=ParticleData._tempRadius;
			var radiusRandom=Math.random();
			particleData.radius[0]=MathUtil.lerp(settings.minStartRadius,settings.maxStartRadius,radiusRandom);
			particleData.radius[1]=MathUtil.lerp(settings.minEndRadius,settings.maxEndRadius,radiusRandom);
			particleData.radian=ParticleData._tempRadian;
			particleData.radian[0]=MathUtil.lerp(settings.minHorizontalStartRadian,settings.maxHorizontalStartRadian,Math.random());
			particleData.radian[1]=MathUtil.lerp(settings.minVerticalStartRadian,settings.maxVerticalStartRadian,Math.random());
			var useEndRadian=settings.useEndRadian;
			particleData.radian[2]=useEndRadian?MathUtil.lerp(settings.minHorizontalEndRadian,settings.maxHorizontalEndRadian,Math.random()):particleData.radian[0];
			particleData.radian[3]=useEndRadian?MathUtil.lerp(settings.minVerticalEndRadian,settings.maxVerticalEndRadian,Math.random()):particleData.radian[1];
			particleData.durationAddScale=settings.ageAddScale *Math.random();
			particleData.time=time;
			return particleData;
		}

		__static(ParticleData,
		['_tempVelocity',function(){return this._tempVelocity=new Float32Array(3);},'_tempStartColor',function(){return this._tempStartColor=new Float32Array(4);},'_tempEndColor',function(){return this._tempEndColor=new Float32Array(4);},'_tempSizeRotation',function(){return this._tempSizeRotation=new Float32Array(3);},'_tempRadius',function(){return this._tempRadius=new Float32Array(2);},'_tempRadian',function(){return this._tempRadian=new Float32Array(4);}
		]);
		return ParticleData;
	})()


	/**
	*@private
	*/
	//class laya.particle.ParticleEmitter
	var ParticleEmitter=(function(){
		function ParticleEmitter(templet,particlesPerSecond,initialPosition){
			this._templet=null;
			this._timeBetweenParticles=NaN;
			this._previousPosition=null;
			this._timeLeftOver=0;
			this._tempVelocity=new Float32Array([0,0,0]);
			this._tempPosition=new Float32Array([0,0,0]);
			this._templet=templet;
			this._timeBetweenParticles=1.0 / particlesPerSecond;
			this._previousPosition=initialPosition;
		}

		__class(ParticleEmitter,'laya.particle.ParticleEmitter');
		var __proto=ParticleEmitter.prototype;
		__proto.update=function(elapsedTime,newPosition){
			elapsedTime=elapsedTime / 1000;
			if (elapsedTime > 0){
				MathUtil.subtractVector3(newPosition,this._previousPosition,this._tempVelocity);
				MathUtil.scaleVector3(this._tempVelocity,1 / elapsedTime,this._tempVelocity);
				var timeToSpend=this._timeLeftOver+elapsedTime;
				var currentTime=-this._timeLeftOver;
				while (timeToSpend > this._timeBetweenParticles){
					currentTime+=this._timeBetweenParticles;
					timeToSpend-=this._timeBetweenParticles;
					MathUtil.lerpVector3(this._previousPosition,newPosition,currentTime / elapsedTime,this._tempPosition);
					this._templet.addParticleArray(this._tempPosition,this._tempVelocity);
				}
				this._timeLeftOver=timeToSpend;
			}
			this._previousPosition[0]=newPosition[0];
			this._previousPosition[1]=newPosition[1];
			this._previousPosition[2]=newPosition[2];
		}

		return ParticleEmitter;
	})()


	/**
	*<code>ParticleSettings</code> 类是粒子配置数据类
	*/
	//class laya.particle.ParticleSetting
	var ParticleSetting=(function(){
		function ParticleSetting(){
			this.textureName=null;
			this.textureCount=1;
			this.maxPartices=100;
			this.duration=1;
			this.ageAddScale=0;
			this.emitterVelocitySensitivity=1;
			this.minStartSize=100;
			this.maxStartSize=100;
			this.minEndSize=100;
			this.maxEndSize=100;
			this.minHorizontalVelocity=0;
			this.maxHorizontalVelocity=0;
			this.minVerticalVelocity=0;
			this.maxVerticalVelocity=0;
			this.endVelocity=1;
			this.minRotateSpeed=0;
			this.maxRotateSpeed=0;
			this.minStartRadius=0;
			this.maxStartRadius=0;
			this.minEndRadius=0;
			this.maxEndRadius=0;
			this.minHorizontalStartRadian=0;
			this.maxHorizontalStartRadian=0;
			this.minVerticalStartRadian=0;
			this.maxVerticalStartRadian=0;
			this.useEndRadian=true;
			this.minHorizontalEndRadian=0;
			this.maxHorizontalEndRadian=0;
			this.minVerticalEndRadian=0;
			this.maxVerticalEndRadian=0;
			this.colorComponentInter=false;
			this.disableColor=false;
			this.blendState=0;
			this.emitterType="null";
			this.emissionRate=0;
			this.sphereEmitterRadius=1;
			this.sphereEmitterVelocity=0;
			this.sphereEmitterVelocityAddVariance=0;
			this.ringEmitterRadius=30;
			this.ringEmitterVelocity=0;
			this.ringEmitterVelocityAddVariance=0;
			this.ringEmitterUp=2;
			this.gravity=new Float32Array([0,0,0]);
			this.minStartColor=new Float32Array([1,1,1,1]);
			this.maxStartColor=new Float32Array([1,1,1,1]);
			this.minEndColor=new Float32Array([1,1,1,1]);
			this.maxEndColor=new Float32Array([1,1,1,1]);
			this.pointEmitterPosition=new Float32Array([0,0,0]);
			this.pointEmitterPositionVariance=new Float32Array([0,0,0]);
			this.pointEmitterVelocity=new Float32Array([0,0,0]);
			this.pointEmitterVelocityAddVariance=new Float32Array([0,0,0]);
			this.boxEmitterCenterPosition=new Float32Array([0,0,0]);
			this.boxEmitterSize=new Float32Array([0,0,0]);
			this.boxEmitterVelocity=new Float32Array([0,0,0]);
			this.boxEmitterVelocityAddVariance=new Float32Array([0,0,0]);
			this.sphereEmitterCenterPosition=new Float32Array([0,0,0]);
			this.ringEmitterCenterPosition=new Float32Array([0,0,0]);
			this.positionVariance=new Float32Array([0,0,0]);
		}

		__class(ParticleSetting,'laya.particle.ParticleSetting');
		ParticleSetting.checkSetting=function(setting){
			var key;
			for (key in ParticleSetting._defaultSetting){
				if (!setting.hasOwnProperty(key)){
					setting[key]=ParticleSetting._defaultSetting[key];
				}
			}
		}

		__static(ParticleSetting,
		['_defaultSetting',function(){return this._defaultSetting=new ParticleSetting();}
		]);
		return ParticleSetting;
	})()


	/**
	*
	*<code>ParticleTemplateBase</code> 类是粒子模板基类
	*
	*/
	//class laya.particle.ParticleTemplateBase
	var ParticleTemplateBase=(function(){
		function ParticleTemplateBase(){
			this.settings=null;
			this.texture=null;
		}

		__class(ParticleTemplateBase,'laya.particle.ParticleTemplateBase');
		var __proto=ParticleTemplateBase.prototype;
		/**
		*添加一个粒子
		*@param position 粒子位置
		*@param velocity 粒子速度
		*
		*/
		__proto.addParticleArray=function(position,velocity){}
		return ParticleTemplateBase;
	})()


	/**
	*@private
	*/
	//class laya.particle.particleUtils.CanvasShader
	var CanvasShader=(function(){
		function CanvasShader(){
			this.u_Duration=NaN;
			this.u_EndVelocity=NaN;
			this.u_Gravity=null;
			this.a_Position=null;
			this.a_Velocity=null;
			this.a_StartColor=null;
			this.a_EndColor=null;
			this.a_SizeRotation=null;
			this.a_Radius=null;
			this.a_Radian=null;
			this.a_AgeAddScale=NaN;
			this.gl_Position=null;
			this.v_Color=null;
			this.oSize=NaN;
			this._color=new Float32Array(4);
			this._position=new Float32Array(3);
		}

		__class(CanvasShader,'laya.particle.particleUtils.CanvasShader');
		var __proto=CanvasShader.prototype;
		__proto.getLen=function(position){
			return Math.sqrt(position[0] *position[0]+position[1] *position[1]+position[2] *position[2]);
		}

		__proto.ComputeParticlePosition=function(position,velocity,age,normalizedAge){
			this._position[0]=position[0];
			this._position[1]=position[1];
			this._position[2]=position[2];
			var startVelocity=this.getLen(velocity);
			var endVelocity=startVelocity *this.u_EndVelocity;
			var velocityIntegral=startVelocity *normalizedAge+(endVelocity-startVelocity)*normalizedAge *normalizedAge / 2.0;
			var lenVelocity=NaN;
			lenVelocity=this.getLen(velocity);
			var i=0,len=0;
			len=3;
			for (i=0;i < len;i++){
				this._position[i]+=this._position[i]+(velocity[i] / lenVelocity)*velocityIntegral *this.u_Duration;
				this._position[i]+=this.u_Gravity[i] *age *normalizedAge;
			};
			var radius=MathUtil.lerp(this.a_Radius[0],this.a_Radius[1],normalizedAge);
			var radianHorizontal=MathUtil.lerp(this.a_Radian[0],this.a_Radian[2],normalizedAge);
			var radianVertical=MathUtil.lerp(this.a_Radian[1],this.a_Radian[3],normalizedAge);
			var r=Math.cos(radianVertical)*radius;
			this._position[1]+=Math.sin(radianVertical)*radius;
			this._position[0]+=Math.cos(radianHorizontal)*r;
			this._position[2]+=Math.sin(radianHorizontal)*r;
			return new Float32Array([this._position[0],this._position[1],0.0,1.0]);
		}

		__proto.ComputeParticleSize=function(startSize,endSize,normalizedAge){
			var size=MathUtil.lerp(startSize,endSize,normalizedAge);
			return size;
		}

		__proto.ComputeParticleRotation=function(rot,age){
			return rot *age;
		}

		__proto.ComputeParticleColor=function(startColor,endColor,normalizedAge){
			var rst=this._color;
			MathUtil.lerpVector4(startColor,endColor,normalizedAge,rst);
			rst[3]=rst[3]*normalizedAge *(1.0-normalizedAge)*(1.0-normalizedAge)*6.7;
			return rst;
		}

		__proto.clamp=function(value,min,max){
			if(value<min)return min;
			if(value>max)return max;
			return value;
		}

		__proto.getData=function(age){
			age *=1.0+this.a_AgeAddScale;
			var normalizedAge=this.clamp(age / this.u_Duration,0.0,1.0);
			this.gl_Position=this.ComputeParticlePosition(this.a_Position,this.a_Velocity,age,normalizedAge);
			var pSize=this.ComputeParticleSize(this.a_SizeRotation[0],this.a_SizeRotation[1],normalizedAge);
			var rotation=this.ComputeParticleRotation(this.a_SizeRotation[2],age);
			this.v_Color=this.ComputeParticleColor(this.a_StartColor,this.a_EndColor,normalizedAge);
			var matric=new Matrix();
			var scale=NaN;
			scale=pSize/this.oSize*2;
			matric.scale(scale,scale);
			matric.rotate(rotation);
			matric.setTranslate(this.gl_Position[0],-this.gl_Position[1]);
			var alpha=NaN;
			alpha=this.v_Color[3];
			return [this.v_Color,alpha,matric,this.v_Color[0]*alpha,this.v_Color[1]*alpha,this.v_Color[2]*alpha];
		}

		return CanvasShader;
	})()


	/**
	*
	*@private
	*
	*@created 2015-8-25 下午3:41:07
	*/
	//class laya.particle.particleUtils.CMDParticle
	var CMDParticle=(function(){
		function CMDParticle(){
			this.maxIndex=0;
			this.cmds=null;
			this.id=0;
		}

		__class(CMDParticle,'laya.particle.particleUtils.CMDParticle');
		var __proto=CMDParticle.prototype;
		__proto.setCmds=function(cmds){
			this.cmds=cmds;
			this.maxIndex=cmds.length-1;
		}

		return CMDParticle;
	})()


	//class laya.particle.particleUtils.PicTool
	var PicTool=(function(){
		function PicTool(){};
		__class(PicTool,'laya.particle.particleUtils.PicTool');
		PicTool.getCanvasPic=function(img,color){
			img=img.bitmap;
			var canvas=new HTMLCanvas("2D");
			var ctx=canvas.getContext('2d');
			canvas.size(img.width,img.height);
			var red=(color >> 16 & 0xFF);
			var green=(color >> 8 & 0xFF);
			var blue=(color & 0xFF);
			if(Render.isConchApp){
				ctx.setFilter(red/255,green/255,blue/255,0);
			}
			ctx.drawImage(img.source,0,0);
			if (!Render.isConchApp){
				var imgdata=ctx.getImageData(0,0,canvas.width,canvas.height);
				var data=imgdata.data;
				for (var i=0,n=data.length;i < n;i+=4){
					if (data[i+3]==0)continue ;
					data[i]=red;
					data[i+1]=green;
					data[i+2]=blue;
				}
				ctx.putImageData(imgdata,0,0);
			}
			return canvas;
		}

		PicTool.getRGBPic=function(img){
			var rst;
			rst=[new Texture(PicTool.getCanvasPic(img,0xFF0000)),new Texture(PicTool.getCanvasPic(img,0x00FF00)),new Texture(PicTool.getCanvasPic(img,0x0000FF))];
			return rst;
		}

		return PicTool;
	})()


	/**
	*
	*@private
	*/
	//class laya.particle.emitter.Emitter2D extends laya.particle.emitter.EmitterBase
	var Emitter2D=(function(_super){
		function Emitter2D(_template){
			this.setting=null;
			this._posRange=null;
			this._canvasTemplate=null;
			this._emitFun=null;
			Emitter2D.__super.call(this);
			this.template=_template;
		}

		__class(Emitter2D,'laya.particle.emitter.Emitter2D',_super);
		var __proto=Emitter2D.prototype;
		__proto.emit=function(){
			_super.prototype.emit.call(this);
			if(this._emitFun!=null)
				this._emitFun();
		}

		__proto.getRandom=function(value){
			return (Math.random()*2-1)*value;
		}

		__proto.webGLEmit=function(){
			var pos=new Float32Array(3);
			pos[0]=this.getRandom(this._posRange[0]);
			pos[1]=this.getRandom(this._posRange[1]);
			pos[2]=this.getRandom(this._posRange[2]);
			var v=new Float32Array(3);
			v[0]=0;
			v[1]=0;
			v[2]=0;
			this._particleTemplate.addParticleArray(pos,v);
		}

		__proto.canvasEmit=function(){
			var pos=new Float32Array(3);
			pos[0]=this.getRandom(this._posRange[0]);
			pos[1]=this.getRandom(this._posRange[1]);
			pos[2]=this.getRandom(this._posRange[2]);
			var v=new Float32Array(3);
			v[0]=0;
			v[1]=0;
			v[2]=0;
			this._particleTemplate.addParticleArray(pos,v);
		}

		__getset(0,__proto,'template',function(){
			return this._particleTemplate;
			},function(template){
			this._particleTemplate=template;
			if (!template){
				this._emitFun=null;
				this.setting=null;
				this._posRange=null;
			};
			this.setting=template.settings;
			this._posRange=this.setting.positionVariance;
			if((this._particleTemplate instanceof laya.particle.ParticleTemplate2D )){
				this._emitFun=this.webGLEmit;
			}else
			if((this._particleTemplate instanceof laya.particle.ParticleTemplateCanvas )){
				this._canvasTemplate=template;
				this._emitFun=this.canvasEmit;
			}
		});

		return Emitter2D;
	})(EmitterBase)


	/**
	*@private
	*/
	//class laya.particle.ParticleTemplateWebGL extends laya.particle.ParticleTemplateBase
	var ParticleTemplateWebGL=(function(_super){
		function ParticleTemplateWebGL(parSetting){
			this._vertices=null;
			this._vertexBuffer=null;
			this._indexBuffer=null;
			this._floatCountPerVertex=29;
			this._firstActiveElement=0;
			this._firstNewElement=0;
			this._firstFreeElement=0;
			this._firstRetiredElement=0;
			this._currentTime=0;
			this._drawCounter=0;
			ParticleTemplateWebGL.__super.call(this);
			this.settings=parSetting;
		}

		__class(ParticleTemplateWebGL,'laya.particle.ParticleTemplateWebGL',_super);
		var __proto=ParticleTemplateWebGL.prototype;
		__proto.initialize=function(){
			this._vertices=new Float32Array(this.settings.maxPartices *this._floatCountPerVertex *4);
			var particleOffset=0;
			for (var i=0;i < this.settings.maxPartices;i++){
				var random=Math.random();
				var cornerYSegement=this.settings.textureCount ? 1.0 / this.settings.textureCount :1.0;
				var cornerY=NaN;
				for (cornerY=0;cornerY < this.settings.textureCount;cornerY+=cornerYSegement){
					if (random < cornerY+cornerYSegement)
						break ;
				}
				particleOffset=i *this._floatCountPerVertex *4;
				this._vertices[particleOffset+this._floatCountPerVertex *0+0]=-1;
				this._vertices[particleOffset+this._floatCountPerVertex *0+1]=-1;
				this._vertices[particleOffset+this._floatCountPerVertex *0+2]=0;
				this._vertices[particleOffset+this._floatCountPerVertex *0+3]=cornerY;
				this._vertices[particleOffset+this._floatCountPerVertex *1+0]=1;
				this._vertices[particleOffset+this._floatCountPerVertex *1+1]=-1;
				this._vertices[particleOffset+this._floatCountPerVertex *1+2]=1;
				this._vertices[particleOffset+this._floatCountPerVertex *1+3]=cornerY;
				this._vertices[particleOffset+this._floatCountPerVertex *2+0]=1;
				this._vertices[particleOffset+this._floatCountPerVertex *2+1]=1;
				this._vertices[particleOffset+this._floatCountPerVertex *2+2]=1;
				this._vertices[particleOffset+this._floatCountPerVertex *2+3]=cornerY+cornerYSegement;
				this._vertices[particleOffset+this._floatCountPerVertex *3+0]=-1;
				this._vertices[particleOffset+this._floatCountPerVertex *3+1]=1;
				this._vertices[particleOffset+this._floatCountPerVertex *3+2]=0;
				this._vertices[particleOffset+this._floatCountPerVertex *3+3]=cornerY+cornerYSegement;
			}
		}

		__proto.loadContent=function(){}
		__proto.update=function(elapsedTime){
			this._currentTime+=elapsedTime / 1000;
			this.retireActiveParticles();
			this.freeRetiredParticles();
			if (this._firstActiveElement==this._firstFreeElement)
				this._currentTime=0;
			if (this._firstRetiredElement==this._firstActiveElement)
				this._drawCounter=0;
		}

		__proto.retireActiveParticles=function(){
			var particleDuration=this.settings.duration;
			while (this._firstActiveElement !=this._firstNewElement){
				var index=this._firstActiveElement *this._floatCountPerVertex *4+28;
				var particleAge=this._currentTime-this._vertices[index];
				if (particleAge < particleDuration)
					break ;
				this._vertices[index]=this._drawCounter;
				this._firstActiveElement++;
				if (this._firstActiveElement >=this.settings.maxPartices)
					this._firstActiveElement=0;
			}
		}

		__proto.freeRetiredParticles=function(){
			while (this._firstRetiredElement !=this._firstActiveElement){
				var age=this._drawCounter-this._vertices[this._firstRetiredElement *this._floatCountPerVertex *4+28];
				if (age < 3)
					break ;
				this._firstRetiredElement++;
				if (this._firstRetiredElement >=this.settings.maxPartices)
					this._firstRetiredElement=0;
			}
		}

		__proto.addNewParticlesToVertexBuffer=function(){}
		__proto.addParticleArray=function(position,velocity){
			var nextFreeParticle=this._firstFreeElement+1;
			if (nextFreeParticle >=this.settings.maxPartices)
				nextFreeParticle=0;
			if (nextFreeParticle===this._firstRetiredElement)
				return;
			var particleData=ParticleData.Create(this.settings,position,velocity,this._currentTime);
			var startIndex=this._firstFreeElement *this._floatCountPerVertex *4;
			for (var i=0;i < 4;i++){
				var j=0,offset=0;
				for (j=0,offset=4;j < 3;j++)
				this._vertices[startIndex+i *this._floatCountPerVertex+offset+j]=particleData.position[j];
				for (j=0,offset=7;j < 3;j++)
				this._vertices[startIndex+i *this._floatCountPerVertex+offset+j]=particleData.velocity[j];
				for (j=0,offset=10;j < 4;j++)
				this._vertices[startIndex+i *this._floatCountPerVertex+offset+j]=particleData.startColor[j];
				for (j=0,offset=14;j < 4;j++)
				this._vertices[startIndex+i *this._floatCountPerVertex+offset+j]=particleData.endColor[j];
				for (j=0,offset=18;j < 3;j++)
				this._vertices[startIndex+i *this._floatCountPerVertex+offset+j]=particleData.sizeRotation[j];
				for (j=0,offset=21;j < 2;j++)
				this._vertices[startIndex+i *this._floatCountPerVertex+offset+j]=particleData.radius[j];
				for (j=0,offset=23;j < 4;j++)
				this._vertices[startIndex+i *this._floatCountPerVertex+offset+j]=particleData.radian[j];
				this._vertices[startIndex+i *this._floatCountPerVertex+27]=particleData.durationAddScale;
				this._vertices[startIndex+i *this._floatCountPerVertex+28]=particleData.time;
			}
			this._firstFreeElement=nextFreeParticle;
		}

		return ParticleTemplateWebGL;
	})(ParticleTemplateBase)


	/**
	*@private
	*/
	//class laya.particle.ParticleTemplateCanvas extends laya.particle.ParticleTemplateBase
	var ParticleTemplateCanvas=(function(_super){
		function ParticleTemplateCanvas(particleSetting){
			this._ready=false;
			this.textureList=[];
			this.particleList=[];
			this.pX=0;
			this.pY=0;
			this.activeParticles=[];
			this.deadParticles=[];
			this.iList=[];
			this._maxNumParticles=0;
			this.textureWidth=NaN;
			this.dTextureWidth=NaN;
			this.colorChange=true;
			this.step=1/60;
			this.canvasShader=new CanvasShader();
			ParticleTemplateCanvas.__super.call(this);
			this.settings=particleSetting;
			this._maxNumParticles=particleSetting.maxPartices;
			this.texture=new Texture();
			this.texture.on(/*laya.events.Event.LOADED*/"loaded",this,this._textureLoaded);
			this.texture.load(particleSetting.textureName);
		}

		__class(ParticleTemplateCanvas,'laya.particle.ParticleTemplateCanvas',_super);
		var __proto=ParticleTemplateCanvas.prototype;
		__proto._textureLoaded=function(e){
			this.setTexture(this.texture);
			this._ready=true;
		}

		__proto.clear=function(clearTexture){
			(clearTexture===void 0)&& (clearTexture=true);
			this.deadParticles.length=0;
			this.activeParticles.length=0;
			this.textureList.length=0;
		}

		/**
		*设置纹理
		*@param texture
		*
		*/
		__proto.setTexture=function(texture){
			this.texture=texture;
			this.textureWidth=texture.width;
			this.dTextureWidth=1/this.textureWidth;
			this.pX=-texture.width*0.5;
			this.pY=-texture.height*0.5;
			this.textureList=ParticleTemplateCanvas.changeTexture(texture,this.textureList);
			this.particleList.length=0;
			this.deadParticles.length=0;
			this.activeParticles.length=0;
		}

		/**
		*创建一个粒子数据
		*@return
		*
		*/
		__proto._createAParticleData=function(position,velocity){
			this.canvasShader.u_EndVelocity=this.settings.endVelocity;
			this.canvasShader.u_Gravity=this.settings.gravity;
			this.canvasShader.u_Duration=this.settings.duration;
			var particle;
			particle=ParticleData.Create(this.settings,position,velocity,0);
			this.canvasShader.a_Position=particle.position;
			this.canvasShader.a_Velocity=particle.velocity;
			this.canvasShader.a_StartColor=particle.startColor;
			this.canvasShader.a_EndColor=particle.endColor;
			this.canvasShader.a_SizeRotation=particle.sizeRotation;
			this.canvasShader.a_Radius=particle.radius;
			this.canvasShader.a_Radian=particle.radian;
			this.canvasShader.a_AgeAddScale=particle.durationAddScale;
			this.canvasShader.oSize=this.textureWidth;
			var rst=new CMDParticle();
			var i=0,len=this.settings.duration/(1+particle.durationAddScale);
			var params=[];
			var mStep=NaN;
			for(i=0;i<len;i+=this.step){
				params.push(this.canvasShader.getData(i));
			}
			rst.id=this.particleList.length;
			this.particleList.push(rst);
			rst.setCmds(params);
			return rst;
		}

		__proto.addParticleArray=function(position,velocity){
			if(!this._ready)return;
			var tParticle;
			if(this.particleList.length<this._maxNumParticles){
				tParticle=this._createAParticleData(position,velocity);
				this.iList[tParticle.id]=0;
				this.activeParticles.push(tParticle);
				}else{
				if(this.deadParticles.length>0){
					tParticle=this.deadParticles.pop();
					this.iList[tParticle.id]=0;
					this.activeParticles.push(tParticle);
				}
			}
		}

		__proto.advanceTime=function(passedTime){
			(passedTime===void 0)&& (passedTime=1);
			if(!this._ready)return;
			var particleList=this.activeParticles;
			var pool=this.deadParticles;
			var i=0,len=particleList.length;
			var tcmd;
			var tI=0;
			var iList=this.iList;
			for(i=len-1;i>-1;i--){
				tcmd=particleList[i];
				tI=iList[tcmd.id];
				if(tI>=tcmd.maxIndex){
					tI=0;
					particleList.splice(i,1);
					pool.push(tcmd);
					}else{
					tI+=1;
				}
				iList[tcmd.id]=tI;
			}
		}

		__proto.render=function(context,x,y){
			if(!this._ready)return;
			if(this.activeParticles.length<1)return;
			if (this.textureList.length < 2)return;
			if (this.settings.disableColor){
				this.noColorRender(context,x,y);
				}else{
				this.canvasRender(context,x,y);
			}
		}

		__proto.noColorRender=function(context,x,y){
			var particleList=this.activeParticles;
			var i=0,len=particleList.length;
			var tcmd;
			var tParam;
			var tAlpha=NaN;
			var px=this.pX,py=this.pY;
			var pw=-px*2,ph=-py*2;
			var tI=0;
			var textureList=this.textureList;
			var iList=this.iList;
			var preAlpha=NaN;
			context.translate(x,y);
			preAlpha=context.ctx.globalAlpha;
			for(i=0;i<len;i++){
				tcmd=particleList[i];
				tI=iList[tcmd.id];
				tParam=tcmd.cmds[tI];
				if (!tParam)continue ;
				if ((tAlpha=tParam[1])<=0.01)continue ;
				context.setAlpha(preAlpha*tAlpha);
				context.drawTextureWithTransform(this.texture,px,py,pw,ph,tParam[2],1);
			}
			context.setAlpha(preAlpha);
			context.translate(-x,-y);
		}

		__proto.canvasRender=function(context,x,y){
			var particleList=this.activeParticles;
			var i=0,len=particleList.length;
			var tcmd;
			var tParam;
			var tAlpha=NaN;
			var px=this.pX,py=this.pY;
			var pw=-px*2,ph=-py*2;
			var tI=0;
			var textureList=this.textureList;
			var iList=this.iList;
			var preAlpha=NaN;
			var preB;
			context.translate(x,y);
			preAlpha=context.ctx.globalAlpha;
			preB=context.ctx.globalCompositeOperation;
			context.blendMode("lighter");
			for(i=0;i<len;i++){
				tcmd=particleList[i];
				tI=iList[tcmd.id];
				tParam=tcmd.cmds[tI];
				if (!tParam)continue ;
				if ((tAlpha=tParam[1])<=0.01)continue ;
				context.save();
				context.transformByMatrix(tParam[2]);
				if(tParam[3]>0.01){
					context.setAlpha(preAlpha*tParam[3]);
					context.drawTexture(textureList[0],px,py,pw,ph);
				}
				if(tParam[4]>0.01){
					context.setAlpha(preAlpha*tParam[4]);
					context.drawTexture(textureList[1],px,py,pw,ph);
				}
				if(tParam[5]>0.01){
					context.setAlpha(preAlpha*tParam[5]);
					context.drawTexture(textureList[2],px,py,pw,ph);
				}
				context.restore();
			}
			context.setAlpha(preAlpha);
			context.translate(-x,-y);
			context.blendMode(preB);
		}

		ParticleTemplateCanvas.changeTexture=function(texture,rst,settings){
			if(!rst)rst=[];
			rst.length=0;
			if (settings&&settings.disableColor){
				rst.push(texture,texture,texture);
				}else{
				Utils.copyArray(rst,PicTool.getRGBPic(texture));
			}
			return rst;
		}

		return ParticleTemplateCanvas;
	})(ParticleTemplateBase)


	/**
	*@private
	*/
	//class laya.particle.ParticleTemplate2D extends laya.particle.ParticleTemplateWebGL
	var ParticleTemplate2D=(function(_super){
		function ParticleTemplate2D(parSetting){
			this._vertexBuffer2D=null;
			this._indexBuffer2D=null;
			this.x=0;
			this.y=0;
			this._blendFn=null;
			this._startTime=0;
			this.sv=new ParticleShaderValue();
			ParticleTemplate2D.__super.call(this,parSetting);
			var _this=this;
			Laya.loader.load(this.settings.textureName,Handler.create(null,function(texture){
				(texture.bitmap).enableMerageInAtlas=false;
				_this.texture=texture;
			}));
			this.sv.u_Duration=this.settings.duration;
			this.sv.u_Gravity=this.settings.gravity;
			this.sv.u_EndVelocity=this.settings.endVelocity;
			this._blendFn=BlendMode.fns[parSetting.blendState];
			this.initialize();
			this._vertexBuffer=this._vertexBuffer2D=VertexBuffer2D.create(-1,/*laya.webgl.WebGLContext.DYNAMIC_DRAW*/0x88E8);
			this._indexBuffer=this._indexBuffer2D=IndexBuffer2D.create(/*laya.webgl.WebGLContext.STATIC_DRAW*/0x88E4);
			this.loadContent();
		}

		__class(ParticleTemplate2D,'laya.particle.ParticleTemplate2D',_super);
		var __proto=ParticleTemplate2D.prototype;
		Laya.imps(__proto,{"laya.webgl.submit.ISubmit":true})
		__proto.getRenderType=function(){return-111}
		__proto.releaseRender=function(){}
		__proto.addParticleArray=function(position,velocity){
			position[0]+=this.x;
			position[1]+=this.y;
			_super.prototype.addParticleArray.call(this,position,velocity);
		}

		__proto.loadContent=function(){
			var indexes=new Uint16Array(this.settings.maxPartices *6);
			for (var i=0;i < this.settings.maxPartices;i++){
				indexes[i *6+0]=(i *4+0);
				indexes[i *6+1]=(i *4+1);
				indexes[i *6+2]=(i *4+2);
				indexes[i *6+3]=(i *4+0);
				indexes[i *6+4]=(i *4+2);
				indexes[i *6+5]=(i *4+3);
			}
			this._indexBuffer2D.clear();
			this._indexBuffer2D.append(indexes);
			this._indexBuffer2D.upload();
		}

		__proto.addNewParticlesToVertexBuffer=function(){
			this._vertexBuffer2D.clear();
			this._vertexBuffer2D.append(this._vertices);
			var start=0;
			if (this._firstNewElement < this._firstFreeElement){
				start=this._firstNewElement *4 *this._floatCountPerVertex *4;
				this._vertexBuffer2D.subUpload(start,start,start+(this._firstFreeElement-this._firstNewElement)*4 *this._floatCountPerVertex *4);
				}else {
				start=this._firstNewElement *4 *this._floatCountPerVertex *4;
				this._vertexBuffer2D.subUpload(start,start,start+(this.settings.maxPartices-this._firstNewElement)*4 *this._floatCountPerVertex *4);
				if (this._firstFreeElement > 0){
					this._vertexBuffer2D.setNeedUpload();
					this._vertexBuffer2D.subUpload(0,0,this._firstFreeElement *4 *this._floatCountPerVertex *4);
				}
			}
			this._firstNewElement=this._firstFreeElement;
		}

		__proto.renderSubmit=function(){
			if (this.texture&&this.texture.loaded){
				this.update(Laya.timer.delta);
				this.sv.u_CurrentTime=this._currentTime;
				if (this._firstNewElement !=this._firstFreeElement){
					this.addNewParticlesToVertexBuffer();
				}
				this.blend();
				if (this._firstActiveElement !=this._firstFreeElement){
					var gl=WebGL.mainContext;
					this._vertexBuffer2D.bind(this._indexBuffer2D);
					this.sv.u_texture=this.texture.source;
					this.sv.upload();
					if (this._firstActiveElement < this._firstFreeElement){
						WebGL.mainContext.drawElements(/*laya.webgl.WebGLContext.TRIANGLES*/0x0004,(this._firstFreeElement-this._firstActiveElement)*6,/*laya.webgl.WebGLContext.UNSIGNED_SHORT*/0x1403,this._firstActiveElement *6 *2);
					}
					else{
						WebGL.mainContext.drawElements(/*laya.webgl.WebGLContext.TRIANGLES*/0x0004,(this.settings.maxPartices-this._firstActiveElement)*6,/*laya.webgl.WebGLContext.UNSIGNED_SHORT*/0x1403,this._firstActiveElement *6 *2);
						if (this._firstFreeElement > 0)
							WebGL.mainContext.drawElements(/*laya.webgl.WebGLContext.TRIANGLES*/0x0004,this._firstFreeElement *6,/*laya.webgl.WebGLContext.UNSIGNED_SHORT*/0x1403,0);
					}
					Stat.drawCall++;
				}
				this._drawCounter++;
			}
			return 1;
		}

		__proto.blend=function(){
			if (BlendMode.activeBlendFunction!==this._blendFn){
				var gl=WebGL.mainContext;
				gl.enable(/*laya.webgl.WebGLContext.BLEND*/0x0BE2);
				this._blendFn(gl);
				BlendMode.activeBlendFunction=this._blendFn;
			}
		}

		__proto.dispose=function(){
			this._indexBuffer2D.dispose();
		}

		ParticleTemplate2D.activeBlendType=-1;
		return ParticleTemplate2D;
	})(ParticleTemplateWebGL)


	/**
	*@private
	*/
	//class laya.particle.shader.value.ParticleShaderValue extends laya.webgl.shader.d2.value.Value2D
	var ParticleShaderValue=(function(_super){
		function ParticleShaderValue(){
			this.a_CornerTextureCoordinate=[4,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,0];
			this.a_Position=[3,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,16];
			this.a_Velocity=[3,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,28];
			this.a_StartColor=[4,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,40];
			this.a_EndColor=[4,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,56];
			this.a_SizeRotation=[3,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,72];
			this.a_Radius=[2,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,84];
			this.a_Radian=[4,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,92];
			this.a_AgeAddScale=[1,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,108];
			this.a_Time=[1,/*laya.webgl.WebGLContext.FLOAT*/0x1406,false,116,112];
			this.u_CurrentTime=NaN;
			this.u_Duration=NaN;
			this.u_Gravity=null;
			this.u_EndVelocity=NaN;
			this.u_texture=null;
			ParticleShaderValue.__super.call(this,0,0);
		}

		__class(ParticleShaderValue,'laya.particle.shader.value.ParticleShaderValue',_super);
		var __proto=ParticleShaderValue.prototype;
		__proto.upload=function(){
			this.refresh();
			ParticleShaderValue.pShader.upload(this);
		}

		__static(ParticleShaderValue,
		['pShader',function(){return this.pShader=new ParticleShader();}
		]);
		return ParticleShaderValue;
	})(Value2D)


	/**
	*<code>Particle2D</code> 类是2D粒子播放类
	*
	*/
	//class laya.particle.Particle2D extends laya.display.Sprite
	var Particle2D=(function(_super){
		function Particle2D(setting){
			this._matrix4=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];
			this._particleTemplate=null;
			this._canvasTemplate=null;
			this._emitter=null;
			this.autoPlay=true;
			Particle2D.__super.call(this);
			if (setting)this.setParticleSetting(setting);
		}

		__class(Particle2D,'laya.particle.Particle2D',_super);
		var __proto=Particle2D.prototype;
		/**
		*加载粒子文件
		*@param url 粒子文件地址
		*/
		__proto.load=function(url){
			Laya.loader.load(url,Handler.create(this,this.setParticleSetting),null,/*laya.net.Loader.JSON*/"json");
		}

		/**
		*设置粒子配置数据
		*@param settings 粒子配置数据
		*/
		__proto.setParticleSetting=function(setting){
			var _$this=this;
			if (!setting)return this.stop();
			ParticleSetting.checkSetting(setting);
			if(/*__JS__ */!window.ConchParticleTemplate2D||Render.isWebGL)this.customRenderEnable=true;
			if (Render.isWebGL){
				this._particleTemplate=new ParticleTemplate2D(setting);
				this.graphics._saveToCmd(Render.context._drawParticle,[this._particleTemplate]);
			}
			else if (Render.isConchApp&&/*__JS__ */window.ConchParticleTemplate2D){
				this._particleTemplate=/*__JS__ */new ConchParticleTemplate2D();
				var _this=this;
				Laya.loader.load(setting.textureName,Handler.create(null,function(texture){
					/*__JS__ */_this._particleTemplate.texture=texture;
					_this._particleTemplate.settings=setting;
					if (Render.isConchNode){
						/*__JS__ */_this.graphics.drawParticle(_this._particleTemplate);
					}
					else{
						_this.graphics._saveToCmd(Render.context._drawParticle,[_$this._particleTemplate]);
					}
				}));
				this._emitter={start:function (){}};
				/*__JS__ */this.play=this._particleTemplate.play.bind(this._particleTemplate);
				/*__JS__ */this.stop=this._particleTemplate.stop.bind(this._particleTemplate);
				if (this.autoPlay)this.play();
				return;
			}
			else {
				this._particleTemplate=this._canvasTemplate=new ParticleTemplateCanvas(setting);
			}
			if (!this._emitter){
				this._emitter=new Emitter2D(this._particleTemplate);
				}else {
				(this._emitter).template=this._particleTemplate;
			}
			if (this.autoPlay){
				this.emitter.start();
				this.play();
			}
		}

		/**
		*播放
		*/
		__proto.play=function(){
			Laya.timer.frameLoop(1,this,this._loop);
		}

		/**
		*停止
		*/
		__proto.stop=function(){
			Laya.timer.clear(this,this._loop);
		}

		/**@private */
		__proto._loop=function(){
			this.advanceTime(1 / 60);
		}

		/**
		*时钟前进
		*@param passedTime 时钟前进时间
		*/
		__proto.advanceTime=function(passedTime){
			(passedTime===void 0)&& (passedTime=1);
			if (this._canvasTemplate){
				this._canvasTemplate.advanceTime(passedTime);
			}
			if (this._emitter){
				this._emitter.advanceTime(passedTime);
			}
		}

		__proto.customRender=function(context,x,y){
			if (Render.isWebGL){
				this._matrix4[0]=context.ctx._curMat.a;
				this._matrix4[1]=context.ctx._curMat.b;
				this._matrix4[4]=context.ctx._curMat.c;
				this._matrix4[5]=context.ctx._curMat.d;
				this._matrix4[12]=context.ctx._curMat.tx;
				this._matrix4[13]=context.ctx._curMat.ty;
				var sv=(this._particleTemplate).sv;
				sv.u_mmat=this._matrix4;
			}
			if (this._canvasTemplate){
				this._canvasTemplate.render(context,x,y);
			}
		}

		__proto.destroy=function(destroyChild){
			(destroyChild===void 0)&& (destroyChild=true);
			if ((this._particleTemplate instanceof laya.particle.ParticleTemplate2D ))
				(this._particleTemplate).dispose();
			_super.prototype.destroy.call(this,destroyChild);
		}

		/**
		*设置 粒子文件地址
		*@param path 粒子文件地址
		*/
		__getset(0,__proto,'url',null,function(url){
			this.load(url);
		});

		/**
		*获取粒子发射器
		*/
		__getset(0,__proto,'emitter',function(){
			return this._emitter;
		});

		return Particle2D;
	})(Sprite)


	/**
	*@private
	*/
	//class laya.particle.shader.ParticleShader extends laya.webgl.shader.Shader
	var ParticleShader=(function(_super){
		function ParticleShader(){
			ParticleShader.__super.call(this,ParticleShader.vs,ParticleShader.ps,"ParticleShader");
		}

		__class(ParticleShader,'laya.particle.shader.ParticleShader',_super);
		__static(ParticleShader,
		['vs',function(){return this.vs="attribute vec4 a_CornerTextureCoordinate;\nattribute vec3 a_Position;\nattribute vec3 a_Velocity;\nattribute vec4 a_StartColor;\nattribute vec4 a_EndColor;\nattribute vec3 a_SizeRotation;\nattribute vec2 a_Radius;\nattribute vec4 a_Radian;\nattribute float a_AgeAddScale;\nattribute float a_Time;\n\nvarying vec4 v_Color;\nvarying vec2 v_TextureCoordinate;\n\nuniform float u_CurrentTime;\nuniform float u_Duration;\nuniform float u_EndVelocity;\nuniform vec3 u_Gravity;\n\n#ifdef PARTICLE3D\n uniform mat4 u_WorldMat;\n uniform mat4 u_View;\n uniform mat4 u_Projection;\n uniform vec2 u_ViewportScale;\n#else\n uniform vec2 size;\n uniform mat4 mmat;\n uniform mat4 u_mmat;\n#endif\n\nvec4 ComputeParticlePosition(in vec3 position, in vec3 velocity,in float age,in float normalizedAge)\n{\n\n   float startVelocity = length(velocity);//起始标量速度\n   float endVelocity = startVelocity * u_EndVelocity;//结束标量速度\n\n   float velocityIntegral = startVelocity * normalizedAge +(endVelocity - startVelocity) * normalizedAge *normalizedAge/2.0;//计算当前速度的标量（单位空间），vt=v0*t+(1/2)*a*(t^2)\n   \n   vec3 addPosition = normalize(velocity) * velocityIntegral * u_Duration;//计算受自身速度影响的位置，转换标量到矢量    \n   addPosition += u_Gravity * age * normalizedAge;//计算受重力影响的位置\n   \n   float radius=mix(a_Radius.x, a_Radius.y, normalizedAge); //计算粒子受半径和角度影响（无需计算角度和半径时，可用宏定义优化屏蔽此计算）\n   float radianHorizontal =mix(a_Radian.x,a_Radian.z,normalizedAge);\n   float radianVertical =mix(a_Radian.y,a_Radian.w,normalizedAge);\n   \n   float r =cos(radianVertical)* radius;\n   addPosition.y += sin(radianVertical) * radius;\n	\n   addPosition.x += cos(radianHorizontal) *r;\n   addPosition.z += sin(radianHorizontal) *r;\n  \n   #ifdef PARTICLE3D\n   position+=addPosition;\n    return  u_Projection*u_View*u_WorldMat*(vec4(position, 1.0));\n   #else\n   addPosition.y=-addPosition.y;//2D粒子位置更新需要取负，2D粒子坐标系Y轴正向朝上\n   position+=addPosition;\n    return  vec4(position,1.0);\n   #endif\n}\n\nfloat ComputeParticleSize(in float startSize,in float endSize, in float normalizedAge)\n{    \n    float size = mix(startSize, endSize, normalizedAge);\n    \n	#ifdef PARTICLE3D\n    //Project the size into screen coordinates.\n     return size * u_Projection[1][1];\n	#else\n	 return size;\n	#endif\n}\n\nmat2 ComputeParticleRotation(in float rot,in float age)\n{    \n    float rotation =rot * age;\n    //计算2x2旋转矩阵.\n    float c = cos(rotation);\n    float s = sin(rotation);\n    return mat2(c, -s, s, c);\n}\n\nvec4 ComputeParticleColor(in vec4 startColor,in vec4 endColor,in float normalizedAge)\n{\n	vec4 color=mix(startColor,endColor,normalizedAge);\n    //硬编码设置，使粒子淡入很快，淡出很慢,6.7的缩放因子把置归一在0到1之间，可以谷歌x*(1-x)*(1-x)*6.7的制图表\n    color.a *= normalizedAge * (1.0-normalizedAge) * (1.0-normalizedAge) * 6.7;\n   \n    return color;\n}\n\nvoid main()\n{\n   float age = u_CurrentTime - a_Time;\n   age *= 1.0 + a_AgeAddScale;\n   float normalizedAge = clamp(age / u_Duration,0.0,1.0);\n   gl_Position = ComputeParticlePosition(a_Position, a_Velocity, age, normalizedAge);//计算粒子位置\n   float pSize = ComputeParticleSize(a_SizeRotation.x,a_SizeRotation.y, normalizedAge);\n   mat2 rotation = ComputeParticleRotation(a_SizeRotation.z, age);\n	\n   #ifdef PARTICLE3D\n	gl_Position.xy += (rotation*a_CornerTextureCoordinate.xy) * pSize * u_ViewportScale;\n   #else\n    mat4 mat=u_mmat*mmat;\n    gl_Position=vec4((mat*gl_Position).xy,0.0,1.0);\n	gl_Position.xy += (rotation*a_CornerTextureCoordinate.xy) * pSize*vec2(mat[0][0],mat[1][1]);\n    gl_Position=vec4((gl_Position.x/size.x-0.5)*2.0,(0.5-gl_Position.y/size.y)*2.0,0.0,1.0);\n   #endif\n   \n   v_Color = ComputeParticleColor(a_StartColor,a_EndColor, normalizedAge);\n   v_TextureCoordinate =a_CornerTextureCoordinate.zw;\n}\n\n"/*__INCLUDESTR__E:/trank/libs/LayaAir/publish/LayaAirPublish/branch/src/particle/src/laya/particle/shader/files/Particle.vs*/;},'ps',function(){return this.ps="#ifdef FSHIGHPRECISION\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n\nvarying vec4 v_Color;\nvarying vec2 v_TextureCoordinate;\nuniform sampler2D u_texture;\n\nvoid main()\n{	\n	gl_FragColor=texture2D(u_texture,v_TextureCoordinate)*v_Color;\n}"/*__INCLUDESTR__E:/trank/libs/LayaAir/publish/LayaAirPublish/branch/src/particle/src/laya/particle/shader/files/Particle.ps*/;}
		]);
		return ParticleShader;
	})(Shader)



})(window,document,Laya);
